package top.lyjwn.todo.security.impl;

import com.alibaba.fastjson2.JSONObject;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.handle.Action;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Handler;
import org.noear.solon.core.route.PathRule;
import org.noear.solon.core.route.RouterInterceptor;
import org.noear.solon.core.route.RouterInterceptorChain;
import top.lyjwn.todo.security.ExemptToken;
import top.lyjwn.todo.security.LoginToken;
import top.lyjwn.todo.template.R;
import top.lyjwn.todo.utils.ContextUtil;

@Component
public class RouterInterceptorImpl implements RouterInterceptor {


    @Inject
    private LoginToken loginToken;

//    public RouterInterceptorImpl() {
//        //异步订阅方式，根据bean name获取Bean
//        Solon.context().getBeanAsync(LoginToken.class, bean -> {
//            loginToken = bean;
//        });
//    }


    @Inject("${todo.token.excludePaths}")
    private String excludePaths;

    @Inject(value = "${todo.token.disable}", required = false)
    private boolean disableToken;

    @Override
    public PathRule pathPatterns() {
        if (excludePaths != null) {
            if (excludePaths.contains(",")) {
                return new PathRule().exclude(excludePaths.split(","));
            } else {
                return new PathRule().exclude(excludePaths);
            }
        }
        return RouterInterceptor.super.pathPatterns();
    }

    @Override
    public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable {
        Action action = ctx.action();
        if (action == null) {
            String res = JSONObject.toJSONString(R.init().error(404, "not found"));
            ContextUtil.handledContext(ctx, res);
            return;
        }
        if (disableToken) {
            chain.doIntercept(ctx, mainHandler);
            return;
        }
        ExemptToken exemptToken = action.method().getAnnotation(ExemptToken.class);
        if (exemptToken == null) {
            String token = ctx.header("token");
            // 如果没有免除token的请求，则进行验证
            if (token == null) {
                //未找到token
                String res = JSONObject.toJSONString(R.init().error(401, "not found token"));
                ContextUtil.handledContext(ctx, res);
                return;
            }
            // 如果用户查找不到，则为假的token
            if (loginToken.getLoginByToken(token) == null) {
                //查询不到用户信息
                String res = JSONObject.toJSONString(R.init().error(401, "the user information cannot be queried"));
                ContextUtil.handledContext(ctx, res);
                return;
            }
            // 验证 token ,加密的正确性
            if (!loginToken.verify(token)) {
                //token验证失败
                String res = JSONObject.toJSONString(R.init().error(401, "token authentication failed"));
                ContextUtil.handledContext(ctx, res);
                return;
            }
            loginToken.postpone(token);
        }
        chain.doIntercept(ctx, mainHandler);

    }


    @Override
    public Object postResult(Context ctx, Object result) throws Throwable {
        return RouterInterceptor.super.postResult(ctx, result);
    }
}
